/*
 *
 *      Copyright (c) 2018-2025, sloth All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the pig4cloud.com developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: sloth
 *
 */

package cn.s1995.sloth.common.core.util;

import cn.s1995.sloth.common.core.constant.enums.hint.Hint;
import cn.s1995.sloth.common.core.constant.enums.hint.HintEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import lombok.experimental.Accessors;

import java.io.Serializable;

/**
 * 响应信息主体
 *
 * @param <T>
 * @author sloth
 */
@Builder
@ToString
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
@Schema(description = "响应信息主体")
public class R<T> implements Serializable {

    private static final long serialVersionUID = 1L;

    @Getter
    @Setter
    @Schema(description = "返回标记：成功标记=0，失败标记=1")
    private int code;

    @Getter
    @Setter
    @Schema(description = "返回信息")
    private String msg;

    @Getter
    @Setter
    @Schema(description = "数据")
    private T data;


    /**
     * 构建消息返回结果
     *
     * @param hint
     * @param data
     * @param args
     * @param <T>
     * @return
     */
    static <T> R<T> buildMessageRestResult(HintEnum hint, T data, Object... args) {
        // 获取国际化信息
        MsgUtils.getMessage(hint, args);
        return restResult(data, hint.getCode(), hint.getMsg());
    }

    static <T> R<T> restResult(T data, int code, String msg) {
        R<T> apiResult = new R<>();
        apiResult.setCode(code);
        apiResult.setData(data);
        apiResult.setMsg(msg);
        return apiResult;
    }

    public static <T> R<T> ok() {
        return buildMessageRestResult(Hint.SUCCESS, null);
    }

    public static <T> R<T> ok(T data) {
        return buildMessageRestResult(Hint.SUCCESS, data);
    }

    public static <T> R<T> ok(T data, String msg) {
        HintEnum hint = Hint.SUCCESS;
        hint.setMsg(msg);
        return restResult(data, hint.getCode(), hint.getMsg());
    }

    public static <T> R<T> ok(HintEnum hint) {
        return ok(hint, null, null);
    }

    public static <T> R<T> ok(HintEnum hint, T data) {
        return ok(hint, data, null);
    }

    public static <T> R<T> ok(HintEnum hint, T data, Object... args) {
        return buildMessageRestResult(hint, data, args);
    }


    public static <T> R<T> failed(HintEnum hint) {
        return failed(hint, null, null);
    }

    public static <T> R<T> failed(HintEnum hint, T data) {
        return failed(hint, data, null);
    }

    public static <T> R<T> failed(HintEnum hint, T data, Object... args) {
        return buildMessageRestResult(hint, data, args);
    }

    public static <T> R<T> failed() {
        return buildMessageRestResult(Hint.FAILED, null);
    }

    public static <T> R<T> failed(String msg) {
        Hint hint = Hint.FAILED;
        hint.setMsg(msg);
        return restResult(null, hint.getCode(), hint.getMsg());
    }

    public static <T> R<T> failed(T data) {
        return buildMessageRestResult(Hint.FAILED, data);
    }

    public static <T> R<T> failed(T data, String msg) {
        Hint hint = Hint.FAILED;
        hint.setMsg(msg);
        return restResult(data, hint.getCode(), hint.getMsg());
    }

    public boolean isOk() {
        return this.code == Hint.SUCCESS.getCode();
    }

}
